Understanding Child Growth & HIV Awareness Worldwide

Author

Lukman Khiruddin

Published

April 22, 2025


Introduction

In every corner of our world, the journey of childhood unfolds with both promise and pitfalls. Where the glow of hope is often shadowed by the realities of stunted growth and the silent spread of HIV.

This dashboard invites you to explore the global landscape of child development, weaving together vivid data on child stunting and HIV awareness to reveal the stark contrasts and hidden connections shaping young lives.

Show code
# Import necessary libraries
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import geopandas as gpd
import json

# Define color scheme to match R's ggplot2
COLORS = {
    'green': '#00BA38',
    'red': '#F8766D',
    'blue': '#619CFF',
    'orange': '#FF9E4A',
    'yellow': '#B79F00',
    'background': '#F0F0F0',
    'grid': '#CCCCCC',
    'text': '#000000'
}

HIV Knowledge Among Youth by Country

This comparison highlights the percentage of young people (aged 15–24) who possess comprehensive, correct knowledge of HIV across countries. By displaying both the leaders and laggards, we can better understand the global disparities in HIV education. This helps policymakers identify both success stories to emulate and areas where urgent action is needed.

Show code for top countries chart
# Filter HIV knowledge data
hiv_knowledge_data = combined_indicators[
    combined_indicators['indicator'].str.contains('comprehensive, correct knowledge of HIV', case=False, na=False)
]
hiv_knowledge_data = hiv_knowledge_data[~hiv_knowledge_data['obs_value'].isna()]

# Get the most recent data for each country and sex
recent_hiv_knowledge = hiv_knowledge_data.sort_values('time_period', ascending=False).groupby(['country', 'sex']).first().reset_index()

# Calculate average knowledge by country and sort
avg_knowledge = recent_hiv_knowledge.groupby('country')['obs_value'].mean().reset_index()
avg_knowledge = avg_knowledge.sort_values('obs_value', ascending=True)  # Ascending for horizontal bars

# Get top 5 countries
top_5_countries = avg_knowledge.tail(5)  # Using tail because we reversed the order

# Create interactive bar chart
fig = go.Figure()

fig.add_trace(go.Bar(
    x=top_5_countries['obs_value'],
    y=top_5_countries['country'],
    orientation='h',
    marker_color=COLORS['green'],
    text=top_5_countries['obs_value'].round(1).astype(str) + '%',
    textposition='outside',
    hovertemplate='<b>%{y}</b><br>HIV Knowledge: %{x:.1f}%<extra></extra>',
    hoverlabel=dict(
        bgcolor='white',
        font_size=12,
        font_family='Arial'
    )
))

fig.update_layout(
    title={
        'text': 'Top 5 Countries with Highest HIV Knowledge<br><sup>Youth (15-24 years)</sup>',
        'x': 0.5,
        'xanchor': 'center'
    },
    xaxis_title='Percentage (%)',
    yaxis_title=None,
    xaxis=dict(range=[0, 75]),
    plot_bgcolor='white',
    showlegend=False,
    height=400,
)

fig.update_xaxes(gridcolor=COLORS['grid'], zeroline=False)
fig.update_yaxes(gridcolor='white')

fig.show()
Show code for bottom countries chart
# Get bottom 5 countries
bottom_5_countries = avg_knowledge.head(5)

# Create interactive bar chart
fig = go.Figure()

fig.add_trace(go.Bar(
    x=bottom_5_countries['obs_value'],
    y=bottom_5_countries['country'],
    orientation='h',
    marker_color=COLORS['green'],
    text=bottom_5_countries['obs_value'].round(1).astype(str) + '%',
    textposition='outside',
    hovertemplate='<b>%{y}</b><br>HIV Knowledge: %{x:.1f}%<extra></extra>',
    hoverlabel=dict(
        bgcolor='white',
        font_size=12,
        font_family='Arial'
    )
))

fig.update_layout(
    title={
        'text': 'Bottom 5 Countries with Lowest HIV Knowledge<br><sup>Youth (15-24 years)</sup>',
        'x': 0.5,
        'xanchor': 'center'
    },
    xaxis_title='Percentage (%)',
    yaxis_title=None,
    xaxis=dict(range=[0, 75]),
    plot_bgcolor='white',
    showlegend=False,
    height=400,
)

fig.update_xaxes(gridcolor=COLORS['grid'], zeroline=False)
fig.update_yaxes(gridcolor='white')

fig.show()

This tabbed comparison reveals stark disparities in HIV knowledge among youth globally. The top-performing countries (primarily in Eastern and Southern Africa) have achieved knowledge rates above 50%, while the lowest-performing countries show rates below 5%.

This significant gap (over 55 percentage points between highest and lowest) highlights implementation disparities in HIV education programs worldwide. Countries at the bottom of the ranking could benefit from adapting successful education strategies from top-performing nations.

Global Gender Gap in HIV Knowledge

This scatterplot displays HIV knowledge levels for young people (aged 15-24) across all countries, comparing males and females. Each point represents a country-gender combination, with the most recent available data for each country. The visualization reveals a clear pattern of gender disparity in HIV knowledge globally.

Show code for global comparison
# Get the most recent data for each country and sex combination
hiv_knowledge_global = (
    hiv_knowledge_data
    .sort_values('time_period', ascending=False)
    .groupby(['country', 'sex'])
    .first()
    .reset_index()
)

# Filter to just Male and Female data
hiv_knowledge_global = hiv_knowledge_global[hiv_knowledge_global['sex'].isin(['Female', 'Male'])]

# Create scatter plot with box plots
fig = go.Figure()

# Add box plots
for sex, color in zip(['Female', 'Male'], [COLORS['red'], COLORS['blue']]):
    sex_data = hiv_knowledge_global[hiv_knowledge_global['sex'] == sex]
    
    # Add box plot
    fig.add_trace(go.Box(
        x=[sex] * len(sex_data),
        y=sex_data['obs_value'],
        name=sex,
        marker_color=color,
        boxpoints='all',
        jitter=0.3,
        pointpos=-1.8,
        marker=dict(
            color=color,
            size=8,
            opacity=0.7
        ),
        line=dict(color='black'),
        fillcolor='white',
        hovertemplate="Country: %{text}<br>Value: %{y:.1f}%<extra></extra>",
        text=sex_data['country']
    ))

# Add horizontal line at median
median_value = hiv_knowledge_global['obs_value'].median()
fig.add_shape(
    type='line',
    x0='Female',
    x1='Male',
    y0=median_value,
    y1=median_value,
    line=dict(
        color='darkgray',
        width=2,
        dash='dash'
    )
)

# Update layout
fig.update_layout(
    title={
        'text': 'Global Gender Gap in HIV Knowledge<br><sup>Most recent data on youth (15-24) with comprehensive HIV knowledge by country</sup>',
        'x': 0.5,
        'xanchor': 'center'
    },
    yaxis_title='HIV Knowledge (%)',
    xaxis_title=None,
    yaxis=dict(range=[0, 70]),
    plot_bgcolor='white',
    height=600,
    showlegend=False,
)

fig.update_yaxes(gridcolor=COLORS['grid'], zeroline=False)

fig.show()